#pragma once
#pragma warning(push)
#pragma warning(disable: 4512)

#include <windows.h>
#include "GraphicsRenderer.h"
#include "EulerCamera.h"
#include "ClassicSimulationInput.h"
#include "Snapshot.h"
#include "KochanekBartelsCurve.h"
#include "SimulationViewCamera.h"
#include "SlerpInterpolator.h"
#include "KdTree.h"
#include <vector>
#include <list>
#include <chrono>

enum SimulationMode
{
	FreeMode,
	ViewMode
};

typedef std::chrono::high_resolution_clock render_clock_t;
typedef std::chrono::time_point<render_clock_t> render_time_t;
typedef std::chrono::duration<double> render_duration_t;

class Simulation
{
public:
	Simulation(GraphicsRenderer& renderer, ClassicSimulationInput& input, std::vector<Snapshot>& snapshots);
	int Run(void);
private:
	void m_SwitchToFreeMode(void);
	void m_SwitchToViewMode(void);
	void m_BuildKdTree();
	void m_UpdateRayBasedOnCamera( void );
	void m_HighLightFirstRayTriangleIntersection( void );
	GraphicsRenderer& m_graphicsRenderer;
	EulerCamera m_cameraFree;
	SimulationViewCamera m_cameraSimulationView;
	ClassicSimulationInput& m_input;
	std::vector<Snapshot> &m_snapshots;
	KochanekBartelsCurve m_kochanekBartelsCurve;
	SlerpInterpolator m_slerpInterpolator;
	SimulationMode m_simulationMode;
	render_time_t m_lastSimulationStart;
	LineList m_ray;
	LineList m_measurementLine;
	DirectX::XMFLOAT3 m_rayPosition[2];
	KdTree *m_KDTree;
	KdTree::KD_NODE_t *m_KDTreeRootNode;
	std::vector<TriangleAccessor> m_listOfTrianglesForKDTree;
	std::vector<TriangleAccessor*> m_listOfTrianglesForKDTree_ptr;
	std::list<RayTriangleIntersection> m_rayTriangleIntersections;
};
#pragma warning(pop)